15.7 执行Shell命令行

我们使用 Groovy 的文件 IO 操作感觉非常好用,例如

  1. package com.easy.kotlin
  2. import org.junit.Test
  3. import org.junit.runner.RunWith
  4. import org.junit.runners.JUnit4
  5. @RunWith(JUnit4)
  6. class ShellExecuteDemoTest {
  7. @Test
  8. def void testShellExecute() {
  9. def p = "ls -R".execute()
  10. def output = p.inputStream.text
  11. println(output)
  12. def fname = "我图.url"
  13. def f = new File(fname)
  14. def lines = f.readLines()
  15. lines.forEach({
  16. println(it)
  17. })
  18. println(f.text)
  19. }
  20. }

Kotlin 中的文件 IO,网络 IO 操作跟 Groovy一样简单。

另外,从上面的代码中我们看到使用 Groovy 执行终端命令非常简单:

  1. def p = "ls -R".execute()
  2. def output = p.inputStream.text

在 Kotlin 中,目前还没有对 String 类和 Process 扩展这样的函数。其实扩展这样的函数非常简单。我们完全可以自己扩展。

首先,我们来扩展 String 的 execute() 函数。

  1. fun String.execute(): Process {
  2. val runtime = Runtime.getRuntime()
  3. return runtime.exec(this)
  4. }

然后,我们来给 Process 类扩展一个 text函数。

  1. fun Process.text(): String {
  2. var output = ""
  3. // 输出 Shell 执行的结果
  4. val inputStream = this.inputStream
  5. val isr = InputStreamReader(inputStream)
  6. val reader = BufferedReader(isr)
  7. var line: String? = ""
  8. while (line != null) {
  9. line = reader.readLine()
  10. output += line + "\n"
  11. }
  12. return output
  13. }

完成了上面两个简单的扩展函数之后,我们就可以在下面的测试代码中,可以像 Groovy 一样执行终端命令了:

  1. val p = "ls -al".execute()
  2. val exitCode = p.waitFor()
  3. val text = p.text()
  4. println(exitCode)
  5. println(text)

实际上,通过之前的很多实例的学习,我们可以看出 Kotlin 的扩展函数相当实用。Kotlin 语言本身API 也大量使用了扩展功能。